﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GamePrep
{
    class GameLogic
    {
        private readonly GameField _gameField;
        private ConsoleDrawer _consoleDrawer;
        private readonly Random _rnd;
        private List<GameNode> nodeList;
        private int _nodesCount;
        private GameNode targetNode;
        private List<GameNode> winnerList;

        public GameLogic(GameField gameField, ConsoleDrawer consoleDrawer, int nodesCount)
        {
            _nodesCount = nodesCount;
            _consoleDrawer = consoleDrawer;
            _gameField = gameField;
            _rnd = new Random();
            winnerList = new List<GameNode>();
            nodeList = new List<GameNode>();
            targetNode = GenerateNodeRandomly(64, 65);
        }

        public void StartGame()
        {
            ConsoleDrawer.DrawGameField(_gameField, '*');
            FillNodeListWithRandomNodes();
            _consoleDrawer.DrawTarget(targetNode);
            do
            {
                for (int i=0; i<nodeList.Count; i++)
                {
                    _consoleDrawer.ClearGameNode(nodeList[i]);
                    MoveNode(nodeList[i]);
                    _consoleDrawer.DrawGameNode(nodeList[i]);
                }
            } while (nodeList.Count>1);
           

        }

        private void MoveNode(GameNode node)
        {
            int nodeDirection = _rnd.Next(1, 5);
            switch (nodeDirection)
            {
                case 1:
                    {
                        if (IsOnField(node.X - 1, node.Y, _gameField) && IsPositionEmpty(node.X - 1, node.Y))
                            node.MoveLeft();
                    }
                    break;

                case 2:
                    {
                        if (IsOnField(node.X + 1, node.Y, _gameField) && IsPositionEmpty(node.X + 1, node.Y))
                            node.MoveRight();
                    }
                    break;

                case 3:
                    {
                        if (IsOnField(node.X, node.Y - 1, _gameField) && IsPositionEmpty(node.X, node.Y - 1))
                            node.MoveUp();
                    }
                    break;

                case 4:
                    {
                        if (IsOnField(node.X, node.Y + 1, _gameField) && IsPositionEmpty(node.X, node.Y + 1))
                            node.MoveDown();
                    }
                    break;
            }
        }

        public bool IsOnTarget(GameNode node)
        {
            for (int i =0; i<nodeList.Count;i++)
            if ((nodeList[i].X == targetNode.X) && (nodeList[i].Y == targetNode.Y))
             return true;
            
            return false;
        }

        static bool IsOnField(int x, int y, GameField gF)
        {

            if ((x == gF.X - 1) || (x == (gF.X + gF.Width)) || ((y == gF.Y - 1) || (y == gF.Y + gF.Height)))
            {
                return false;
            }

            return true;
        }

        private bool IsPositionEmpty(int x, int y)
        {

            foreach (var i in nodeList)
                if (x == i.X && y == i.Y)
                    return false;

            return true;
        }

        private void FillNodeListWithRandomNodes()
        {
            for (int i = 0; i < _nodesCount; i++)
            {
                nodeList.Add(GenerateNodeRandomly());
            }
        }

        private GameNode GenerateNodeRandomly(int minSymbol = 1, int maxSymbol = 7)
        {
            int randomX = 0;
            int randomY = 0;
            do
            {
                randomX = _rnd.Next(_gameField.X, _gameField.X + _gameField.Width);
                randomY = _rnd.Next(_gameField.Y, _gameField.Y + _gameField.Height);
            } while (!IsPositionEmpty(randomX, randomY));

            return new GameNode(randomX, randomY, (Char) _rnd.Next(minSymbol, maxSymbol));

        }

    }
}
